Skip to content

gitavk/test-env

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

test-env

Набор Docker-приложений для проверки сканеров безопасности и pen-test инструментов: разнородные сервисы, которые сканер может обнаружить, классифицировать и (в demo-файлах) проэксплуатировать. Окружение для разработки и демонстрации, не продакшн-деплой.

Файлы — независимые compose-оверлеи, поднимаются поверх базового compose.yml (кроме vuln-demo.yml и vuln-demo-glpi.yml, которые самодостаточны):

# все команды — из корня этого репозитория

# база: nginx + gitea + postgres + confluence
docker compose -f compose.yml up -d

# + honeypot: разнородные сервисы на одном хосте
docker compose -f compose.yml -f honeypot.yml up -d

# уязвимый Roundcube (CVE-2025-49113) — отдельно, самодостаточен
docker compose -f vuln-demo.yml up -d

# уязвимый GLPI (CVE-2022-35914) — отдельно, самодостаточен, поднимается ~1-2 минуты (установка БД)
docker compose -f vuln-demo-glpi.yml up -d

compose.yml — база

nginx + gitea + postgres + confluence. Версии актуальные (не уязвимые) — сервисы нужны для проверки discovery и классификации продуктов, а не для поиска реальных CVE.

honeypot.yml — honeypot-набор

4 сервиса-приманки (ftp/nntp/irc/vnc баннеры) на одном хосте — по разнородности сервисов сканер должен распознать хост как honeypot.

vuln-demo.yml — реальная уязвимость (CVE-2025-49113)

roundcube/roundcubemail:1.6.10-apache — последний релиз перед фиксом в 1.6.11. В отличие от compose.yml, это реально уязвимый сервис (Roundcube RCE, CVSS 9.9, CISA KEV): сканер с соответствующей nuclei-проверкой должен найти её по-настоящему — через классификацию product: "roundcube" (title логин-страницы) и неавторизованный version-fingerprint внутри nuclei-шаблона (подробнее — в шапке самого vuln-demo.yml).

vuln-demo-glpi.yml — реальная уязвимость (CVE-2022-35914)

darkvills/glpi:10.0.2 + mysql:8.4.10. Как и Roundcube, это реально уязвимый сервис (GLPI RCE через тестовый файл библиотеки htmlawed, CVSS 9.8, CISA KEV): уязвимость эксплуатируется тем же nuclei-шаблоном, который её находит (POST с hhook=exec возвращает содержимое /etc/passwd).

GLPI — система учёта IT-парка (ITAM) и service desk.

БД здесь не для эксплойта (уязвимый файл — отдельный vendor-скрипт вне роутинга GLPI и отдаётся независимо от состояния установки), а для классификации: без config_db.php GLPI на любой странице отдаёт заглушку "Missing configuration" — ни title, ни nuclei-шаблон glpi-status-page не сработают, и продукт не распознаётся. Поэтому glpi в этом файле зависит от db (healthcheck) и при первом старте сам прогоняет glpi:database:install перед запуском Apache (подробности — в шапке самого vuln-demo-glpi.yml).

Официальный образ glpi/glpi на Docker Hub хранит только пропатченные версии, а сборка версии 10.0.2 из официального Dockerfile ломается — composer.lock ссылается на нестабильный сторонний сайт (bioinformatics.org, отдаёт 503). Поэтому здесь используется готовый образ стороннего автора (darkvills/glpi:10.0.2) — это заведомо жертвенный контейнер (весь смысл — чтобы его взломала наша же проверка), без сборки и без сетевых зависимостей при каждом поднятии.

Оба демо (vuln-demo.yml и vuln-demo-glpi.yml) рассчитаны на запуск сканера с отдельной машины — target виден как обычный сосед по LAN на опубликованном порту. Ни один из файлов не использует трюки с network_mode: bridge для обхода WiFi hairpin (см. ниже) — раньше он был в vuln-demo.yml, но для реального сценария (сканер и target на разных машинах) он не нужен: обход имел смысл только когда сканер и target подняты на одном хосте.

⚠️ WiFi hairpin — если всё же поднимать сканер и target на одной машине

Если сканер и demo-контейнер подняты на одной Linux-машине, и эта машина смотрит в сеть через WiFi-адаптер, скан может не найти сервис вообще — не из-за бага в сканере или каталоге проверок, а из-за особенности самого WiFi.

Условие узкое — срабатывает только при одновременном совпадении всех трёх: нативный Linux (не гостевая ОС) + WiFi + сканер и target на одной машине. Во всех остальных случаях всё в порядке:

Хост сканера WiFi Ethernet
Native Linux (Docker прямо на хосте) ⚠️ hairpin ✅ ок
VM любой ОС (Linux/Windows/macOS-гость) ✅ ок ✅ ок
macOS/Windows + Docker Desktop ✅ ок ✅ ок
сканер и target на разных машинах ✅ ок (не применимо) ✅ ок (не применимо)

Docker Desktop на macOS/Windows тоже попадает в "VM"-строку, даже если сам ноутбук на WiFi: Docker Desktop сам работает внутри Linux VM (см. ниже), так что nmap там видит виртуальный адаптер, а не настоящий WiFi-интерфейс — hairpin специфичен именно для Linux-хоста, где Docker установлен нативно.

Механика: discovery-шаг (nmap) сканер запускает с network_mode: host — это осознанный выбор, иначе на Linux он не увидит ни реальную LAN, ни другие docker-сети (в отличие от macOS/Windows, где Docker сам работает внутри Linux VM). Хост, обращаясь к своему же внешнему IP на docker-опубликованный порт (docker run -p 8081:80 ... → сканируем <свой-WiFi-IP>:8081), гоняет пакет туда-обратно через один и тот же физический интерфейс (hairpin). На Ethernet это обычно штатно NAT'ится обратно. На WiFi — часто нет: пакет уходит на точку доступа и не возвращается тем же путём (rp_filter/reverse-path защита ядра расценивает такой ответ как "марсианский" и дропает, либо сама точка доступа не поддерживает client-to-client hairpin). Итог: nmap видит порт закрытым, хотя контейнер реально отвечает.

Проверить эмпирически (замените IP/порт на свои):

# видит порт (обычный контейнер на bridge, без hairpin через WiFi):
docker run --rm --network host --cap-add NET_RAW instrumentisto/nmap:7.98 \
  -sV -Pn --open -oX - <IP контейнера из `docker inspect`>

# не видит (hairpin через WiFi-IP хоста):
docker run --rm --network host --cap-add NET_RAW instrumentisto/nmap:7.98 \
  -sV -Pn --open -oX - <WiFi IP хоста>

Специального обхода в demo-файлах сейчас нет — простейший способ избежать проблемы: гонять сканер и target на разных машинах (как и задумано), либо через Ethernet, либо в VM.

Почему это не всплывает в VM (например, Windows-хост с Debian-гостем): гостевая ОС видит виртуальный сетевой адаптер (virtio-net/e1000/vmxnet3), который для её ядра — обычный Ethernet-подобный интерфейс, независимо от того, как физически подключён к сети хост-гипервизор. Hairpin внутри VM разруливает виртуальный свитч гипервизора, а не настоящая 802.11-передача — проблема просто не воспроизводится.

About

Demo docker compose files

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors